# -*- coding: utf-8 -*-
import json

from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
from odoo.tools import float_is_zero, float_compare
import datetime

class HrExpense(models.Model):
    _inherit = 'hr.expense'
    account_move_id = fields.Many2one('account.move', string='Journal Entry', ondelete='set null', copy=False,
                                      readonly=True)
    name = fields.Char('用途', readonly=True, required=True,
                       states={'draft': [('readonly', False)], 'reported': [('readonly', False)],
                               'refused': [('readonly', False)]})
    unit_amount = fields.Float("Unit Price", readonly=True, required=True,
                               states={'draft': [('readonly', False)], 'reported': [('readonly', False)],
                                       'refused': [('readonly', False)]}, digits='Product Price')
    state = fields.Selection([
        ('draft', u'草稿'),
        ('cancel', u'被拒'),
        ('to approve', u'审核中'),
        ('rejected', u'被拒'),
        ('approve', u'待过账'),
        ('post', u'待支付'),
        ('done', u'完成'),
    ], string=u"状态", default='draft', track_visibility='onchange',related='sheet_id.state',store=True)
    unit_amount = fields.Float("Unit Price", readonly=True, required=True,
                               states={'draft': [('readonly', False)], 'reported': [('readonly', False)],
                                       'refused': [('readonly', False)]}, digits='Product Price')
    total_amount_company = fields.Monetary("Total (Company Currency)", compute='_compute_total_amount_company',
                                           store=True, currency_field='company_currency_id')
    company_currency_id = fields.Many2one('res.currency', string="Report Company Currency",
                                          related='sheet_id.currency_id', store=True, readonly=False)


class HrExpenseSheet(models.Model):
    _name = 'hr.expense.sheet'
    _inherit = ['hr.expense.sheet','base.approve']
    _order = 'id desc'
    state = fields.Selection([
        ('draft', u'草稿'),
        ('cancel', u'被拒'),
        ('to approve', u'审核中'),
        ('rejected', u'被拒'),
        ('approve', u'待过账'),
        ('post', u'待支付'),
        ('done', u'完成'),
    ], string=u"状态", default='draft', track_visibility='onchange')
    apply_date=fields.Date(string='日期',default=fields.date.today())
    account_move_id = fields.Many2one('account.move', string='Journal Entry', ondelete='set null', copy=False, readonly=True)


    barcode=fields.Char(compute='compute_barcode',string=u'工号')
    @api.depends('employee_id')
    def compute_barcode(self):
        for r in self:
            r.barcode=r.employee_id.sudo().barcode
    # 暂支抵扣明细物理存储
    payment_reconcile_ids = fields.One2many('advance.payment.expense.reconcile', 'sheet_id')
    approved_id = fields.Many2one('res.users', help=u'记录一下谁审核通过了这张单据')

    payment_balance=fields.Float(related='employee_id.payment_balance',string=u'借款余额')
    # rt_approval_record_ids = fields.One2many('rt.approval.records', 'rt_res_id',
    #                                          domain=[('rt_res_model', '=', 'hr.expense.sheet')])
    company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True,
                                 states={'draft': [('readonly', False)]}, default=lambda self: self.env.company)
    currency_id = fields.Many2one('res.currency', string='Currency', readonly=True,
                                  states={'draft': [('readonly', False)]},
                                  default=lambda self: self.env.company.currency_id)
    account_payment_ids = fields.One2many('account.payment', 'res_id',
                                          domain=[('res_model', '=', 'hr.expense.sheet')])
    approval_record_ids = fields.One2many('approval.records', 'res_id',
                                          domain=[('res_model', '=', 'hr.expense.sheet')])
    approve_flow_ids = fields.One2many('approve.flow', 'res_id',domain=[('res_model', '=', 'hr.expense.sheet')])

    remark=fields.Text(string='备注')
    def set_to_done(self):
        self.state = 'approve'

    def mail_get_link(self):
        """ 获取报价单form视图的url """
        base_url = self.env["ir.config_parameter"].sudo().get_param("web.base.url")
        action = self.env.ref("hr_expense_inherit.action_my_hr_expense_to_approve").id
        web_url = "/web?#id=%d&action=%d&view_type=form" % (self.id, action)
        return base_url + web_url

    def send_to_approve_email(self, user_id):

        mail_template = self.env.ref('hr_expense_inherit.template_hr_expense_sheet')
        mail_template.send_mail(self.id, force_send=True,
                                email_values={'email_to': user_id.partner_id.email})





    expense_line_ids = fields.One2many('hr.expense', 'sheet_id', string='报销明细',
                                       states={'approve': [('readonly', True)], 'done': [('readonly', True)],
                                               'draft': [('readonly', False)],
                                               'post': [('readonly', True)]}, copy=True)

    def action_cancel(self):
        for sheet in self:
            # 取消过账分录
            if sheet.account_move_id:
                sheet.account_move_id.with_context({'force_delete':True}).button_cancel()
                sheet.account_move_id.with_context({'force_delete':True}).unlink()
            move_id = self.env['account.move'].search([('ref', '=', self.name)])
            # 取消抵扣分录
            if move_id:
                move_id.button_cancel()
                move_id.with_context({'force_delete':True}).unlink()
            # 取消暂支抵扣
            if sheet.payment_reconcile_ids:
                sheet.payment_reconcile_ids.unlink()
            # sheet.cancel_deduct_payment()
            # 取消付款分录

            if sheet.account_payment_ids:
                for payment in sheet.account_payment_ids:
                    payment.action_draft()
                    payment.move_name=''
                    payment.unlink()
            # b_id = self.env['rt.employee.salary.balance'].search(
            #     [('res_model', '=', sheet._name), ('res_id', '=', sheet.id)])
            # b_id.unlink()

            sheet.state = 'approve'

    def unlink(self):
        for r in self:
            if r.payment_reconcile_ids:
                raise UserError(u'请先取消预支款抵扣再删除')
        return super(HrExpenseSheet, self).unlink()





    @api.onchange('accounting_date')
    def on_change_accounting_date(self):
        if self.name and self.accounting_date:
            move_id = self.env['account.move'].search([('ref', '=', self.name)])
            if move_id:
                move_id.write({
                    'date': self.accounting_date
                })

    # def action_approve(self, remark='', need_notification=True):
    #     if not self.rt_user_can_approve:
    #         return
    #     self.create_approve_record(status='0')
    #     self.create_approve_list()
    #     reject_str = u'审核通过'
    #     if remark:
    #         reject_str = u"审核通过：" + remark
    #     self.message_post(reject_str)
    #     # PM 审核逻辑
    #     if not self.rt_to_approval_department_id:
    #         p_rt_to_approval_project_id = self.rt_to_approval_project_id
    #         to_approve_project_id = self.rt_to_approval_project_id.get_to_approve_project_id_by_amount(
    #             res_model=self._name, res_id=self.id)
    #         if not to_approve_project_id:
    #             self.action_approve_done()
    #         elif p_rt_to_approval_project_id.manager_id.final_approve:
    #             self.rt_to_approval_project_id = self.env.ref('rt_base.project_project_root').id
    #         else:
    #             self.rt_to_approval_project_id = to_approve_project_id.id
    #         return
    #     # 終審審核邏輯
    #     if self.rt_to_approval_department_id.final_approve:
    #         self.action_approve_done()
    #         return
    #     to_approve_department_id = self.rt_to_approval_department_id.get_to_approve_department_id_by_amount(
    #         res_model=self._name, res_id=self.id)
    #     if not to_approve_department_id:
    #         self.action_approve_done()
    #     else:
    #         self.rt_to_approval_department_id = to_approve_department_id.id





    @api.depends('expense_line_ids')
    def _get_full_name(self):
        for r in self:
            r.full_description = ';'.join(r.expense_line_ids.mapped('name'))

    full_description = fields.Char(string=u'消费用途', compute='_get_full_name', store=True)

    name = fields.Char(required=False, copy=False)
    account_payment_ids = fields.One2many('account.payment', 'res_id', domain=[('res_model', '=', 'hr.expense.sheet')])
    department_id = fields.Many2one('hr.department', string=u'部门',
                                    track_visibility='onchange',
                                    states={'post': [('readonly', False)], 'done': [('readonly', False)],
                                            'salary': [('readonly', False)]})

    has_payment_line_ids = fields.Boolean(compute='_compute_has_payment_or_reconcile_ids')
    reconciled_amount = fields.Float(string=u'暂支抵扣金额', compute='_compute_has_payment_or_reconcile_ids')
    paid_amount = fields.Float(string=u'付款金额', compute='_compute_has_payment_or_reconcile_ids')
    to_pay_amount = fields.Float(compute='_compute_has_payment_or_reconcile_ids')
    has_payment_ids = fields.Boolean(compute='_compute_has_payment_or_reconcile_ids')
    payment_amount = fields.Float(compute='_compute_has_payment_or_reconcile_ids')
    reconciled_ids = fields.One2many('advance.payment.expense.reconcile', 'sheet_id')
    has_reconciled_ids=fields.Boolean(compute='compute_has_reconciled_ids')
    def compute_has_reconciled_ids(self):
        for r in self:
            if r.reconciled_ids:
                r.has_reconciled_ids=True
            else:
                r.has_reconciled_ids=False
    has_advance_payment_ids = fields.Boolean(compute='_compute_advance_payment_info_json')
    deduct_button_disable = fields.Boolean(compute='_compute_advance_payment_info_json')




    @api.depends('account_payment_ids', 'payment_reconcile_ids')
    def _compute_has_payment_or_reconcile_ids(self):
        for sheet in self:
            if sheet.account_payment_ids:
                sheet.paid_amount = sum(payment.amount for payment in sheet.account_payment_ids)
                sheet.has_payment_ids = True
            else:
                sheet.has_payment_ids = False
            if sheet.payment_reconcile_ids:
                sheet.has_payment_line_ids = True
                sheet.reconciled_amount = sum(line.amount for line in sheet.payment_reconcile_ids)
            else:
                sheet.has_payment_line_ids = False
            sheet.to_pay_amount = sheet.total_amount - sheet.paid_amount - sheet.reconciled_amount
            sheet.payment_amount = sheet.total_amount - sheet.reconciled_amount

    # @api.multi
    # def action_cancel(self):
    #     for sheet in self:
    #         # 取消过账分录
    #         if sheet.account_move_id:
    #             sheet.account_move_id.button_cancel()
    #             sheet.account_move_id.unlink()
    #         move_id = self.env['account.move'].search([('ref', '=', self.name)])
    #         # 取消抵扣分录
    #         if move_id:
    #             move_id.button_cancel()
    #             move_id.unlink()
    #         # 取消暂支抵扣
    #         # sheet.cancel_deduct_payment()
    #         # 取消付款分录
    #         if sheet.account_payment_ids:
    #             for payment in sheet.account_payment_ids:
    #                 payment.cancel()
    #                 payment.unlink()
    #         b_id = self.env['rt.employee.salary.balance'].search(
    #             [('res_model', '=', sheet._name), ('res_id', '=', sheet.id)])
    #         b_id.unlink()
    #
    #         sheet.state = 'approve'

    @api.onchange('department_id')
    def _onchange_department_id(self):
        for line in self.expense_line_ids:
            line.department_id = line.sheet_id.department_id.id


    def cancel_deduct_payment(self):
        for sheet in self:
            if sheet.payment_reconcile_ids:
                for line in sheet.payment_reconcile_ids:
                    line.unlink()

    @api.model
    def create(self, vals):
        if vals.get('name', 'New') == 'New':
            vals['name'] = self.env['ir.sequence'].next_by_code('hr.expense.sheet') or '/'

        return super(HrExpenseSheet, self).create(vals)

    def reset_expense_sheets(self):
        self.hr_expense_sheet_post()



    def register_payment_action(self):

        amount = self.to_pay_amount
        if float_is_zero(amount,precision_digits=1):
            self.set_to_paid()

        context = {'default_payment_type': 'outbound', 'default_amount': amount,

                }

        return {
            'name': u'付款',
            'view_type': 'form',
            'view_mode': 'form',
            # 'view_id': False,
            'res_model': 'hr.expense.sheet.register.payment.wizard',
            'domain': [],
            'context': dict(context, active_ids=self.ids),
            'type': 'ir.actions.act_window',
            'target': 'new',
        }

    @api.model
    def _create_set_followers(self, values):
        # Add the followers at creation, so they can be notified
        employee_id = values.get('employee_id')
        if not employee_id:
            return

        employee = self.env['hr.employee'].browse(employee_id)
        users = self._get_users_to_subscribe(employee=employee) - self.env.user
        values['message_follower_ids'] = []
        # MailFollowers = self.env['mail.followers']
        # for partner in users.mapped('partner_id'):
        #     values['message_follower_ids'] += MailFollowers._add_follower_command(self._name, [], {partner.id: None}, {})[0]

    def _add_followers(self):
        users = self.sudo()._get_users_to_subscribe()
        self.message_subscribe_users(user_ids=users.ids)

    def create_payment_reconcile(self):
        payment_expense_reconcile = self.env['advance.payment.expense.reconcile']
        advance_ids=self.env['expense.advance.payment'].search([('employee_id','=',self.employee_id.id),('state','=','done'),('reconciled','!=',True)])
        for advance_id in advance_ids:
            if not float_is_zero(self.to_pay_amount,precision_digits=1)  and not float_is_zero(advance_id.advance_payment_reminding,precision_digits=1):
                if float_compare(self.to_pay_amount,advance_id.advance_payment_reminding,precision_digits=1)!=1:
                    amount=self.to_pay_amount
                else:
                    amount=advance_id.advance_payment_reminding
                payment_expense_reconcile.create({
                    'advance_payment_id': advance_id.id,
                    'sheet_id': self.id,
                    'amount': amount
                })


        # while not float_is_zero(self.to_pay_amount,precision_digits=1) and :




    def action_sheet_move_create(self):
        if any(sheet.state != 'approve' for sheet in self):
            raise UserError(_("You can only generate accounting entry for approved expense(s)."))

        if any(not sheet.journal_id for sheet in self):
            raise UserError(_("Expenses must have an expense journal specified to generate accounting entries."))

        expense_line_ids = self.mapped('expense_line_ids')\
            .filtered(lambda r: not float_is_zero(r.total_amount, precision_rounding=(r.currency_id or self.env.company.currency_id).rounding))
        res = expense_line_ids.sudo().action_move_create()
        self.create_payment_reconcile()

        if not self.accounting_date:
            self.accounting_date = self.account_move_id.date

        if self.payment_mode == 'own_account' and expense_line_ids:
            self.write({'state': 'post'})
        else:
            self.write({'state': 'done'})
        self.activity_update()
        return res


class HrExpenseRefuseWizard(models.TransientModel):
    _inherit = "hr.expense.refuse.wizard"

    def expense_refuse_reason(self):
        self.ensure_one()

        context = dict(self._context or {})
        active_ids = context.get('active_ids', [])
        expense_sheet = self.env['hr.expense.sheet'].browse(active_ids)
        expense_sheet.refuse_expenses(self.description)
        return {'type': 'ir.actions.act_window_close'}
